// ==UserScript==
// @name         阿目批量改价
// @updateURL    https://gitee.com/amutravel/amu/raw/master/priceAndStock/multiPriceAndStock.user.js
// @version      2020.9.09
// @description  阿目批量改价
// @author       ╮(╯▽╰)╭
// @include      *://erp.himudidi.com/platform/product_list/id/*
// @include      *://erp.himudidi.com/admin/product/parent_product.html*
// @include      *://erp.himudidi.com/product/parent_product*
// @run-at       document-end
// @grant        unsafeWindow
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @connect      erp.himudidi.com
// @grant        window.close
// @require      https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js
// ==/UserScript==
function formatDate(date, offset=0){
  try {
      let t = new Date(new Date(date).getTime() + 86400000*offset);
      return `${t.getFullYear()}-${(t.getMonth()+1).toString().padStart(2,'0')}-${t.getDate().toString().padStart(2,'0')}`;
    } catch (error) {
    return '';
  }
}

// 区分母产品页面(mother)，或者平台产品页面(platform)
function pageType(){
  if(location.href.includes('/product/parent_product')){
    return 'mother'
  }else if(new RegExp('http://erp.himudidi.com/platform/product_list/id/').test(location.href)){
      return 'platform'
  }else{
    return 'unknow'
  }
}


function findAmuCheckPackages(){
  let selector = '#tablelist input.ids:checked';
  let tmp = [];
  let nameColumnIndex = pageType()==='mother' ? 3 : 5;
  document.querySelectorAll(selector).forEach(elem=>{
    let children = elem.parentElement.parentElement.children;
    tmp.push({
      id: elem.value,
      name: children[nameColumnIndex].textContent
    })
  })
  return tmp
}


GM_addStyle(`

.ic-success-circle::before{
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E %3Cpath fill='%2319be6b' d='M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z'%3E%3C/path%3E %3C/svg%3E");
}
.ic-error-circle::before{
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E %3Cpath fill='%23ed4014' d='M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm101.8-262.2L295.6 256l62.2 62.2c4.7 4.7 4.7 12.3 0 17l-22.6 22.6c-4.7 4.7-12.3 4.7-17 0L256 295.6l-62.2 62.2c-4.7 4.7-12.3 4.7-17 0l-22.6-22.6c-4.7-4.7-4.7-12.3 0-17l62.2-62.2-62.2-62.2c-4.7-4.7-4.7-12.3 0-17l22.6-22.6c4.7-4.7 12.3-4.7 17 0l62.2 62.2 62.2-62.2c4.7-4.7 12.3-4.7 17 0l22.6 22.6c4.7 4.7 4.7 12.3 0 17z'%3E%3C/path%3E %3C/svg%3E");
}
.ic-warning-circle:before{
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E %3Cpath fill='%23ff9900' d='M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z'%3E%3C/path%3E %3C/svg%3E");
}
.ic-plus:before{
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E %3Cpath fill='%23000000' d='M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z'%3E%3C/path%3E %3C/svg%3E");
}
.ic-minus:before{
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E %3Cpath d='M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z'%3E%3C/path%3E %3C/svg%3E");
}
.ic::before{
  width: 1em;
  display: inline-block;
  vertical-align: middle;
}

`);
// jshint esversion:6
/*! 最后修改于 2020-8-22 */
const Amu = {
  setMotherCalendarURL: "http://erp.himudidi.com/product_calendar/set_calendar.html",
  setChildCalendarURL: "http://erp.himudidi.com/platform_product_calendar/set_calendar.html",
  getCalendarURL: "http://erp.himudidi.com/api/calendar/get",
  platformCode: {
    meituanVocation: '35',
    ctripVocation: '41',
    qunarVocation: '33',
    mafengwoVocation: '37',
    fliggyVocation: '58'
  },

  formatDate(date, offset=0){
    try {
      let t = new Date(new Date(date).getTime() + 86400000*offset);
      return `${t.getFullYear()}-${(t.getMonth()+1).toString().padStart(2,'0')}-${t.getDate().toString().padStart(2,'0')}`;
    } catch (error) {
      return '';
    }
  },
 
  // 设置价格日历，在调用这个函数之前，应该做好数据校验的工作
  // 这里子产品和母产品设置价格都考虑到了
  // setCalendar: function ({product_id, cost, stock, days, weeks}, callback) {
  // isWeek 默认false 按日期修改，true 按星期几来修改
  setCalendar: function (dataJson, callback = null, isWeek = false) {
    if(!dataJson.hasOwnProperty('product_id') || !(dataJson.days instanceof Array) && !(dataJson.weeks instanceof Array)){return false;}
    const dataProps = [
      //一般来说，cost 成本 和 stock 是一起的，用于母产品的设置
      // price 价格 用于只产品，会附带平台，还有状态status(利润/成本)
      // price_status, 1 利润, 2 售价
      'cost',           // 底价, 如果这个不想更改，一定要设置为 '', 否则默认值比如 null 会把价格库存都清空
      'stock',          // 库存，如果这个不想更改，一定要设置为 '', 否则默认值比如 null 会把库存都改为 0
      'price',          // 价格
      'price_status',   // 利润或售价
      'time',           // 日期范围，比如 2020-08-21 - 2020-08-31, 是按星期模式修改时候需要
    ];
    let postString = `product_id[]=${dataJson.product_id}`;
    if(dataJson.hasOwnProperty('platform_id')){
      postString += '&platform_id=' + dataJson.platform_id;
    }
    dataProps.map(v=>{
      if(dataJson.hasOwnProperty(v)){
        postString += `&items[0][${v}]=${dataJson[v]}`;
      }
    });
    try {
      isWeek
       ? postString += '&items[0][week][]=' + dataJson.weeks.join('&items[0][week][]=')
       : postString += '&items[0][date][]=' + dataJson.days.join('&items[0][date][]=');

      GM_xmlhttpRequest({
        url: dataJson.hasOwnProperty('platform_id') ? this.setChildCalendarURL: this.setMotherCalendarURL,
        method: "POST",
        headers: { 'Content-Type': 'application/x-www-form-urlencoded; boundary=&; charset=UTF-8' },
        responseType: "json",
        data: encodeURI(postString),
        onload: function (data) { if (callback) { callback(data, dataJson);} },
        onerror: function (data) { if (callback) { callback(data, dataJson);} }
      });
    } catch (error) {
      console.log("A.setCalendar Error:\n", dataJson, error);
    }

  }, 

  getCalendar: function(id, length=60, start=this.formatDate(new Date)){
    let postData = {
      id: id,  // 供应商商品id(阿目云平台产品ID)，必须
      length: length, // 长度，日期的长度，可空，接口默认30
      start: start,  // 开始日期，可空，默认当天
    };
    return new Promise((resolve,reject)=>{
      GM_xmlhttpRequest({
        url: this.getCalendarURL,
        method: "POST",
        headers: { 'Content-Type': 'application/x-www-form-urlencoded; boundary=&; charset=UTF-8' },
        data: baseFunction.concatData(postData),
        responseType: "json",
        onload: function (data) { resolve(data.response); },
        onerror: function(data) { reject(data.response); }
      });
    });
  },

  // 产品价格日历，直接问价格，通过阿目云产品ID
  getPlatformCalendar: function(amuyunId, startDate, endDate, platform){
    let calendarURL;
    if(platform){
      // 平台产品，子产品
      calendarURL = `http://erp.himudidi.com/platform_product_calendar/get_calendar/id/${amuyunId}/p_id/${this.platformCode[platform]}.html`;
    }else{
      // 母产品
      calendarURL = `http://erp.himudidi.com/product_calendar/get_calendar/id/${amuyunId}.html`;
    }
    let postData = {
      start: startDate,
      end: endDate
    };
    return new Promise((resolve,reject)=>{
      GM_xmlhttpRequest({
        url: calendarURL,
        method: "POST",
        headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
        data: baseFunction.concatData(postData),
        responseType: "json",
        onload: function (data) { resolve(data.response); },
        onerror: function(data) { reject(data.response); }
      });

    });
  },

  // 提供平台产品ID，获得所有套餐在阿目云关联的平台子产品ID givePlatformProductIdGetAmuRelatedChildrenProductIds
  givePidGetAmuChildrens(productId){
    return new Promise((resolve)=>{
      GM_xmlhttpRequest({
        method:"GET",
        url:`http://erp.himudidi.com/api/package/get?product_platform_number=${productId}`,
        timeout:3000,
        responseType: "json",
        onload:function(response){
          if(response.response.status == 1 && response.response.data.length>0){
            let tmp = {};
            for(let item of response.response.data){
              tmp[item.product_platform_package_id] = item.product_platform_relation_id;
            }
            resolve(tmp);
          }else{
            console.log("===== Amu->givePidGetAmuChildrens->ERROR =====\n", response);
            resolve({});
          }
        },
        onerror:function(response){
          console.log("===== Amu->givePidGetAmuChildrens->ERROR =====\n", response);
          resolve({});
        }
      });
    });
  },

  gotoCalendarPage(amuyunId, platform){
    let url = `http://erp.himudidi.com/platform_product_calendar/index/id/${amuyunId}/p_id/${this.platformCode[platform]}.html`
    window.open(url, '_blank');
  },
  // 打开同步套餐页面
  gotoSynchroPage(amuyunId, platform){
    let url =`http://erp.himudidi.com/synchro/choose/product_pid/${amuyunId}/platform_id/${this.platformCode[platform]}.html`;
    window.open(url, "_blank");
  }
  // A End
};

const baseFunction = {
  // xhr中，json 转化为 form data 格式
  json2formData: function(jsonObj){

  },
  concatData: function(dataJson){
    let dataString = '';
    for (let i in dataJson) {
      dataString += `${i}=${dataJson[i]}&`;
    }
    return dataString.slice(0, -1);
  },
  // 这里不做错误检查了，保证数据来源就好
  formatDate: function(date, offset=0){
    try {
      let t = new Date(new Date(date).getTime() + 86400000*offset);
      return `${t.getFullYear()}-${(t.getMonth()+1).toString().padStart(2,'0')}-${t.getDate().toString().padStart(2,'0')}`;
    } catch (error) {
      return '';
    }
  }
};


// import {GM_addStyle} from './fns.js'
GM_addStyle(`
  .nacl-daterangepicker{display:grid;grid-template-rows:28px auto;margin:0;padding:0}
  .daterangepicker-range{display:flex;justify-content:space-between;border:1px solid #e4e4e4;padding:3px 10px;max-height:28px;border-radius:.2em;background:#fff}
  .daterangepicker-range input{border:none;outline:0;font-size:12px;padding:0;text-align:center}
  .daterangepicker-months{position:absolute;min-width:500px;display:grid;grid-template-columns:50% 50%;border-radius:.2em;margin:0px 0 0 0;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);background:#FFF}
  .daterangepicker-months>div{padding:5px;border:1px solid #e4e4e4}
  .nacl-daterangepicker .month-head{display:flex;justify-content:space-between;padding:0}
  .nacl-daterangepicker .month-text{flex:1;text-align:center;padding:5px 0 0;font-weight:bold;cursor:pointer;font-size:15px}
  .nacl-daterangepicker .month-box{overflow:hidden}
  .nacl-daterangepicker .week-div{border-bottom:1px solid #e4e4e4}
  .nacl-daterangepicker .month-box>span{float:left;width:14.28%;text-align:center;padding:3px 0;margin:2px 0}
  .nacl-daterangepicker .other-month{color:#999}
  .nacl-daterangepicker .disabled{pointer-events:none;background-color:#eeeeee;color:#999}
  .nacl-daterangepicker .current-month{color:#333}
  .nacl-daterangepicker .ym-prev-next,.nacl-daterangepicker .month-box>span.current-month,.nacl-daterangepicker .month-box>span.other-month{display:inline-flex;min-width:30px;height:30px;align-items:center;justify-content:center;cursor:pointer;font-size: 13px;}
  .nacl-daterangepicker span.current-month:hover{background:#00BDFF;color:#fff}
  .nacl-daterangepicker .ym-prev-next:hover,.nacl-daterangepicker .today-flag,.nacl-daterangepicker .selected-style{background-color:orange;color:#fff}
  .nacl-daterangepicker .current-month.between-style{background-color:lightskyblue}
  .nacl-daterangepicker .active-style{background:#00BDFF;color:#fff}
  .nacl-daterangepicker .ym-prev-next{font-size:2em!important;font-weight:bolder}
`);

const daterangePicker = {
  template: `
    <div :class="['nacl-daterangepicker', pickerClass]"
      ref="drpContainer"
      @scroll="updateCalendarXY"
      :style="{width: typeof width === 'string' ? width : width+'px'
      }">
      <div class="daterangepicker-range" 
        ref="drpInput">
      <input @focus="show" @blur="handleBlur" v-model="range[0]" type="text" :style="{width: (width-30)/2+'px'}">
      <span>-</span>
      <input @focus="show" @blur="handleBlur" v-model="range[1]" type="text" :style="{width: (width-30)/2+'px'}">
      </div>
      <div v-if="showMonths" class="daterangepicker-months"
        :style="{
          zIndex: 999999999, 
          width: typeof width === 'string' ? width : width+'px'
        }">
        <!-- 第一个月 -->
        <div>
          <div class="month-head">
            <div>
              <span @click="prevYearFun" class="ym-prev-next">«</span>
              <span @click="prevMonthFun" class="ym-prev-next">‹</span>
            </div>
            <div class="month-text">{{formatDate(new Date(year, month)).slice(0,7)}}</div>
            <div v-if="type==='date'">
              <span @click="nextMonthFun" class="ym-prev-next">›</span>
              <span @click="nextYearFun" class="ym-prev-next">»</span>
            </div>
          </div>
          <div class="week-div month-box">
            <span>日</span>
            <span>一</span>
            <span>二</span>
            <span>三</span>
            <span>四</span>
            <span>五</span>
            <span>六</span>
          </div>
          <div class="schedule-bd month-box">
            <span
              v-for="item in month1"
              :class="[
                item.isCurrentMonth ? 'current-month' : 'other-month',
                {'between-style':betweenDate.includes(item.day)},
                item.cls
              ]"
              :data-day="item.day"
              @click="seleDate"
              @mouseover.prevent="hoverDate"
              v-html="item.day.slice(-2)">
            </span>
          </div>
        </div>
        <!-- 第二个月 -->
        <div>
          <div class="month-head">
            <div v-if="type==='date'">
              <span @click="prevYearFun" class="ym-prev-next">«</span>
              <span @click="prevMonthFun" class="ym-prev-next">‹</span>
            </div>
            <div class="month-text" >{{formatDate(new Date(year, month+1)).slice(0,7)}}</div>
            <div>
              <span @click="nextMonthFun" class="ym-prev-next">›</span>
              <span @click="nextYearFun" class="ym-prev-next">»</span>
            </div>
          </div>
          <div class="week-div month-box">
            <span>日</span>
            <span>一</span>
            <span>二</span>
            <span>三</span>
            <span>四</span>
            <span>五</span>
            <span>六</span>
          </div>
          <div class="schedule-bd month-box">
            <span
              v-for="item in month2"
              :class="[
                item.isCurrentMonth ? 'current-month' : 'other-month',
                {'between-style':betweenDate.includes(item.day)},
                item.cls
              ]"
              :data-day="item.day"
              @click="seleDate"
              @mouseover.prevent="hoverDate"
              v-html="item.day.slice(-2)">
            </span>
          </div>
        </div>
      </div>
    </div>`,
  model:{
    prop: 'range',
    event: 'seleDate'
  },
  props: {
    width: {type: String|Number, default: 250},
    pickerClass: {type: String},
    type: 'daterange', // date 显示一个月， daterange 显示2个月
    range: {type: Array, default(){return [formatDate(new Date()), formatDate(new Date(), 7)]}},
    curDate: {type: Date, default(){return new Date()}},
    disabledDate: {type: Array, default(){return []}},
    selectedDate: {type: Array, default(){return []}},
    disabledBefore: {type: String, default:''},
    disabledAfter: {type: String, default:''},
  },
  data(){
    return{
      showMonths: false,
      startEnd: this.range.slice(),
      year: this.curDate.getFullYear(),
      month: this.curDate.getMonth(),
      currentYear: this.curDate.getFullYear(),
      currentMonth: this.curDate.getMonth(),
      currentDay: this.curDate.getDate(),
      activeDate: '',
      betweenDate: [],
      month1: [],
      month2: [],
      hideTimer: '',
      xy: [0,0],
      scroll: null
    }
  },
  created(){
    this.updateMonth(new Date(this.range[0]).getFullYear(),new Date(this.range[0]).getMonth());
    this.betweenDate = this.generateBetweenDate(this.range);
  },
  methods: {
    formatDate(date, offset=0){
      try {
          let t = new Date(new Date(date).getTime() + 86400000*offset);
          return `${t.getFullYear()}-${(t.getMonth()+1).toString().padStart(2,'0')}-${t.getDate().toString().padStart(2,'0')}`;
        } catch (error) {
        return '';
      }
    },
    concatDate(y, m, d) {
      var symbol = '-';
      if (m) {
        m = (m.toString())[1] ? m : '0' + m;
      }
      if (d) {
        d = (d.toString())[1] ? d : '0' + d;
      }
      return y + (m ? symbol + m : '') + (d ? symbol + d : '');
    },
    constructMonth(year, month){
      let days = [];
      var fullDay = new Date(year, month + 1, 0).getDate()
        , startWeek = new Date(year, month, 1).getDay()
        , total = (fullDay + startWeek) % 7 == 0 ? (fullDay + startWeek) : fullDay + startWeek + (7 - (fullDay + startWeek) % 7)
        ;
      for (var i = 0; i < total; i++) {
        var nowDate = this.formatDate(new Date(year, month,  i-startWeek+1))
        var nowTimestamp = new Date(nowDate).getTime();
        var isDisbale = this.disabledDate.indexOf(nowDate) > -1;
        var isSelected = this.selectedDate.indexOf(nowDate) > -1;
        let isBetween = this.betweenDate.indexOf(nowDate) > -1;
        if (i < startWeek) {
          days.push({
            isCurrentMonth: false,
            cls: '',
            day: nowDate
          })
        } else if (i < (startWeek + fullDay)) {
          var addClass = '';
          if (isDisbale) {
            addClass = 'disabled'
          } else {
            isSelected && (addClass = 'selected-style');
            isBetween && (addClass = 'between-style')
            this.activeDate == nowDate && (addClass = 'active-style');
            this.concatDate(this.currentYear, this.currentMonth + 1, this.currentDay) == nowDate && (addClass = 'today-flag');
          }
          if (this.disabledBefore && nowTimestamp < this.disabledBefore) {
            addClass = 'disabled'
          }
          if (this.disabledAfter && nowTimestamp > this.disabledAfter) {
            addClass = 'disabled'
          }
          days.push({
            isCurrentMonth: true,
            cls: addClass,
            day: nowDate
          })
        } else {
          days.push({
            isCurrentMonth: false,
            cls: '',
            day: nowDate
          })
        }
      }
      return days;
    },
    updateMonth(year,month){
        this.month1 = this.constructMonth(year, month)
        
        if (month + 1 > 11) {
          year += 1;
          month = 0;
        } else {
          month += 1;
        }
        this.month2 = this.constructMonth(year, month)
    },
    nextMonthFun() {
      if (this.month + 1 > 11) {
        this.year += 1;
        this.month = 0;
      } else {
        this.month += 1;
      }

      this.updateMonth(this.year,this.month);
      this.show();
      // opt.nextMonthCb && opt.nextMonthCb(year, month + 1);
    },
    nextYearFun() {
      this.year += 1;
      this.updateMonth(this.year,this.month);
      this.show();
      // opt.nextYeayCb && opt.nextYeayCb(year, month + 1);
    },
    prevMonthFun() {
      if (this.month - 1 < 0) {
        this.year -= 1;
        this.month = 11;
      } else {
        this.month -= 1;
      }
      this.updateMonth(this.year,this.month);
      this.show();
      // opt.prevMonthCb && opt.prevMonthCb(year, month + 1);
    },
    prevYearFun() {
      this.year -= 1;
      this.updateMonth(this.year,this.month);
      this.show();
      // opt.prevYearCb && opt.prevYearCb(year, month + 1);
    },
    seleDate(e){
      if(this.startEnd[1]){
        this.$set(this, 'startEnd', [e.target.dataset.day, '']);
        this.show()
      }else{
        this.$set(this, 'startEnd', [this.startEnd[0], e.target.dataset.day].sort())
        this.$emit('change', this.startEnd);
        this.$set(this, 'betweenDate', this.generateBetweenDate(this.startEnd));
        this.showMonths = false;
      }
    },
    generateBetweenDate(arr){
      let tmpArray = [];
      let startEnd = arr.sort();
      let width = (new Date(startEnd[1]).getTime() - new Date(startEnd[0]).getTime())/86400000;
      for(let i = 0; i <= width; i++){
        tmpArray.push(this.formatDate(startEnd[0], i))
      }
      return tmpArray;
    },
    hoverDate(e){
      if(this.startEnd[1]) return; // 如果已经选定好2个日期，那么久不再处理鼠标上的日期
      this.$set(this, 'betweenDate', this.generateBetweenDate([this.startEnd[0], e.target.dataset.day]));
    },
    updateCalendarXY(e){
      
      // console.log(e, e.screenX, e.screenY)
      // return 
      if(!this.scroll){
        this.scroll = 1;
        setTimeout(() => {
          
          // scrollIntoView(this.$refs.drpContainer, this.$refs.drpInput)
          this.$refs.drpInput.scrollIntoView({block: 'center'})
          this.scroll = null
        }, 200);
      }
    },
    show(){
      this.showMonths = true;
      clearTimeout(this.hideTimer)
    },
    handleBlur(e){
      this.hideTimer = setTimeout(() => {
        this.showMonths = false;
      }, 200);
    },
  },
}
// vue weekdays component
GM_addStyle(`
  .weekdays button{
    display: inline-block;
    min-width: 30px;
    max-height: 28px;
    border: 1px solid #456;
    font-size: 14px;
    border-radius: 0.2em;
    cursor: pointer;
    background-color: #fff;
    padding: 2px 4px;
    margin-left: 3px;
  }
  .weekdays button[data-sel]:active,
  .weekdays button[data-sel]{
    border: 1px solid #409EFF !important;
    color: white;
    background: #409EFF !important;
  }
`);
const weekdaysComp = {
  template: `
    <span class="weekdays">
      <button :data-sel="allSel" @click="toggleSel('7')">全选</button>
      <button
        v-for="d in Object.keys(data)"
        :key="d"
        :data-sel="data[d]"
        @click="toggleSel(d)">{{names[d]}}</button>
    </span>
  `,
  props: {
    data: {type: Object, default:()=>{return {'0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true}}}
  },
  data(){
    return{
      names: {'0': '日', '1': '一', '2': '二', '3': '三', '4': '四', '5': '五', '6': '六'}
    }
  },
  methods:{
    toggleSel(key){
      if(key !== '7'){
        this.data[key] = !this.data[key];
      }
      else{
        let isSelAll = this.allSel;
        '0123456'.split('').forEach(v=>{
          this.data[v] = !isSelAll
        })
      }
      this.$emit('change', this.data, this.$attrs)
    },
  },
  computed: {
    allSel(){
      return this.data['0'] && this.data['1'] && this.data['2'] && this.data['3'] && this.data['4'] && this.data['5'] && this.data['6'];
    }
  }
};
// vue pns-item component
// css 需要外部的 .ic .ic-plus .ic-minus
GM_addStyle(`
  input.pns{
    max-height: 28px;
    width: 50px;
    border: 1px solid #789;
    border-radius: 0.2em;
    font-size: 14px;
    padding: 4px;
  }  
  .pnsitem button[data-sel]{
    border: 1px solid #409EFF !important;
    color: white;
    background: #409EFF !important;
  }
  .pnsitem .status{
    zoom: 1.5;
  }
`);
const pnsItemComp = {
  template: `
    <li class="pnsitem">
      <!-- :range="data.range" -->
      <daterange-picker
        v-model="data.range"
        :width="200"
        picker-class="picker-class"
        @change="dateRangeChange"
        style="display: inline-block;"
        ></daterange-picker>
      <button @click="addRemove('add')" class="ic ic-plus"></button>
      <button @click="addRemove('remove')" class="ic ic-minus"></button>
      <weekdays :data="data.weekdays" @change="handleChange('weekdays')"></weekdays>
      <input v-model.number="data.price" @input="handleChange('price')" type="text" 
        :placeholder="pagetype==='mother' ? '成本' : (data.price_status==1 ? '利润' : '售价')" class="pns">
      <input v-model.number="data.stock" @input="handleChange('stock')" type="text"
        v-if="pagetype==='mother'" placeholder="库存" class="pns">
      <button v-if="pagetype=='platform'" @click="handleChange('price_status', 1)" :data-sel="data.price_status==1">利润</button>
      <button v-if="pagetype=='platform'" @click="handleChange('price_status', 2)" :data-sel="data.price_status==2">售价</button>
      <span v-if="data.status.length" :class="'status ic ic-'+data.status+'-circle'" size="small"></span>
    </li>
  `,
  props:{
    pagetype: '', // 这个取决于 pageType,母产品不显示，平台产品显示
    data: {type:Object, default:()=>({
      range: '',
      weekdays: {'0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true},
      price: '',
      stock: '',
      price_status: 1, // 1 利润模式，2 售价模式
      status: '',  // 这个status 只是为了显示修改结果是否成功
    })}
  },
  components:{
    'weekdays': weekdaysComp,
    'daterange-picker': daterangePicker
  },
  methods:{
    handleChange(type, value=undefined){
      this.$emit('change', {
        type: type,
        value: value ? value : this.data[type]
      }, this.$attrs)
    },
    addRemove(type){this.$emit('addremove', type, this.$attrs)},
    dateRangeChange(range){
      this.handleChange('range', range);
    }
  },
};
GM_addStyle(`
  #multiSetPns *{
    font-size: 12px;
  }
  #multiSetPns button{
    cursor: pointer;
    border: 1px solid #999;
    border-radius: 3px;
    padding: 3px 8px;
    margin-left: 2px;
    background: white;
    box-shadow: 1px 2px #666;
  }
  .picker-class{
    line-height: 25px;
    max-height: 25px;
  }
  .daterangepicker-range{
    border-color: #999;
  }
  #multiSetPns{
    position: fixed;
    top: 0;
    background: white;
    z-index: 9999;
    width: 100%;
    text-align: center;
    margin: auto;
    padding: 0;
    height: auto;
    max-height: 80%;
    overflow: auto;
    box-shadow: 0px 5px 10px 10px #555;
  }
  .dad-div,.son-div{
    display: grid;
    grid-template-columns: 35% auto;
    padding: 5px 30px;
  }
  .son-div:nth-child(odd) {
    background: #D6D6D6;
  }
  .pkg-name{
    text-align: left;
    vertical-align: middle;
    margin-right: 20px;
  }
  .pkg-stamps{
    text-align: left;
  }
  .pkg-name span{
    font-weight: bolder;
  }
  input[type=checkbox]{
    zoom: 1.5;
  }
  #multiPnsFoot{
    position: sticky;
    bottom: 0;
    background: #EEEEEE;
    padding: 10px;
    /*margin-top: 5px;  这里我还没有调好 daterangePicker 日历显示位置，所以只好用 padding-top 来弥补一下。调好了之后，可以改成 5px */
    margin-top: 290px;
    box-shadow: 0 -2px 10px 0px #333;
  }
`);
let defalutWeekdays = {'0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true};
let dadItem = {range: [formatDate(new Date), formatDate(new Date, 7)], weekdays: {}, stock: '', price: '', price_status: 1, status:''};
const appComp = {
  template: `<div v-show="isShow" id="multiSetPns">
    <div class="dad-div">
      <li class="pkg-name"><label><input v-model="selAll" type="checkbox" name="selAll"><span>全选</span></label></li>
      <div class="pkg-stamps">
        <pns-item
          v-for="t in Object.keys(dad.stamps)"
          :key="t"
          :data="dad.stamps[t]"
          :pagetype="pageType"
          :stamp="t"
          type='dad'
          @change="wdChange"
          @addremove="addRemoveStamp"
        ></pns-item>
      </div>
    </div>
    <div v-if="Object.keys(son).length" v-for="id in Object.keys(son)" class="son-div">
      <li class="pkg-name">
        <label><input v-model="son[id].sel" type="checkbox"><span>{{son[id].name || ''}}</span></label>
      </li>
      <div class="pkg-stamps">
        <pns-item
          v-for="t in Object.keys(son[id].stamps)"
          :key="t"
          :data="son[id].stamps[t]"
          :pagetype="pageType"
          :stamp="t"
          type='son'
          :sonid='id'
          @change="wdChange"
          @addremove="addRemoveStamp"
        ></pns-item>
      </div>
    </div>
    <div id="multiPnsFoot">
      <button v-show="showModifyButton" @click="multiSetCalendar">确定</button>
      <button v-show="!showModifyButton" @click="clearStatus">继续修改</button>
      <button @click="hide">{{showModifyButton ? '取消' : '完成'}}</button>
    </div>
  </div>`,
  data(){
    return {
      isShow: false,
      pageType: pageType(), // 母产品 或者 平台产品页面。
      dad: { stamps: {} },
      son: { '0': {} },
      showModifyButton: true,
    }
  },
  components:{
    'pns-item': pnsItemComp,
  },
  methods:{
    nowStamp(){return Date.now()},
    cloneJson(d){return JSON.parse(JSON.stringify(d))},
    reset(){
      this.$set(this.dad, 'stamps', {});
      Object.keys(this.son).forEach(id=>{
        this.$set(this.son[id], 'stamps', {})
      });
    },
    initStamp(){
      this.$set(this.dad, 'stamps', {});
      Object.keys(this.son).forEach(id=>{
        this.$set(this.son[id], 'stamps', {})
      })

      let t = this.nowStamp();
      this.$set(this.dad.stamps, t, Object.assign(dadItem, {weekdays: defalutWeekdays}))
      Object.keys(this.son).forEach(id=>{
        this.$set(this.son[id].stamps, t, this.cloneJson(this.dad.stamps[t]))
      })
    },
    addRemoveStamp(type, data){
      type === 'add' ? this.addStamp(data) : this.removeStamp(data);
    },
    addStamp(data){
      let t = this.nowStamp();
      if(data.type === 'dad'){
        this.$set(this.dad.stamps, t, this.cloneJson(this.dad.stamps[data.stamp]))
        Object.keys(this.son).forEach(id=>{
          this.$set(this.son[id].stamps, t, this.cloneJson(this.dad.stamps[t]))
        })
      }else{
        this.$set(this.son[data.sonid].stamps, t, this.cloneJson(this.son[data.sonid].stamps[data.stamp]))
      }
    },
    removeStamp(data){
      if(data.type === 'dad'){
        delete this.dad.stamps[data.stamp];
        Object.keys(this.son).forEach(id=>{
          delete this.son[id].stamps[data.stamp]
        })
      }else{
        delete this.son[data.sonid].stamps[data.stamp]
      }
      if(!Object.keys(this.dad.stamps).length){this.reset();this.initStamp()}
      this.$forceUpdate()
    },
    wdChange(v, data){
      if(data.type === 'son'){
        // 子组变动
        this.$set(this.son[data.sonid].stamps[data.stamp], v.type, v.value)
      }else{
        // 父组变动
        this.$set(this.dad.stamps[data.stamp], v.type, v.value);
        Object.keys(this.son).forEach(id=>{
          this.$set(this.son[id].stamps[data.stamp], v.type, this.cloneJson(v.value))
        })
      }
    },
    updateSon(pkgs){
      let son = {};
      for(let i =0; i<pkgs.length; i++){
        son[i.toString()] = {
          id: pkgs[i].id,
          name: pkgs[i].name,
          stamps: {},
          sel: true
        }
      }
      this.reset();
      this.$set(this, 'son', son);
      this.initStamp();
      this.isShow = true;
    },
    oneSetCalendar(id, stamp, delay=0){
      let d = this.son[id].stamps[stamp];
      return new Promise(resolve=>{
        let data = {
          product_id: this.son[id].id,
          time: `${d.range[0]}+-+${d.range[1]}`,
          weeks: Object.keys(d.weekdays).filter(k=>{ if(d.weekdays[k]) return k}),
        };
        try {
          if(this.pageType === 'mother'){
            if(d.price==='' && d.stock===''){
              this.$set(this.son[id].stamps[stamp], 'status', 'warning')
              throw {type: 'warning', info: '成本和库存，至少要填写1个'}
            }else{
              Object.assign(data, {cost: d.price, stock: d.stock})
            }
          }else{
            if(d.price===''){
              this.$set(this.son[id].stamps[stamp], 'status', 'warning')
              throw {type: 'warning', info: '利润或者售价，一定要填写'}
            }else{
              Object.assign(data, {
                price: d.price, 
                price_status: d.price_status,
                platform_id: location.pathname.match(/\d\d/g)[0]
              })
            }
          }

          setTimeout(() => {
            // 这里延时发送请求，可以保证同一个套餐，后面的设置晚于前面的设置发送请求，一般就能够保证覆盖效果
            Amu.setCalendar(data, (res)=>{
              if(res.status === 200 && res.response){
                if(res.response.status === 1){
                  this.$set(this.son[id].stamps[stamp], 'status', 'success')
                }else{
                  this.$set(this.son[id].stamps[stamp], 'status', 'error');
                  throw {type: 'error', info: res.response.info}
                }
              }else if(res.status===404){
                this.$set(this.son[id].stamps[stamp], 'status', 'error');
                throw {type: 'error', info:"批量改价请求的参数有问题，请检查"}
              }
              resolve('success')
            }, true);
          }, delay);
        } catch (e) {
          // 这里还有错误没有处理好，比如批量改平台产品，缺少平台ID的时候，就没有处理这种情况，后续再改进吧
          console.log(e)
          resolve(e.type)
        }
      })
    },
    multiSetCalendar(){
      Object.keys(this.son).forEach(id=>{
        if(this.son[id].sel){
          Object.keys(this.son[id].stamps).forEach(async (stamp, i)=>{
            let tmp = await this.oneSetCalendar(id, stamp, i*100);
            console.log(tmp)
          })
        }
      })
      this.showModifyButton = false;
    },
    clearStatus(){
      Object.keys(this.son).forEach(id=>{
        Object.keys(this.son[id].stamps).forEach(stamp=>{
          this.son[id].stamps[stamp].status = ''
        })
      })
      this.showModifyButton = true;
    },
    hide(){
      this.showModifyButton = true;
      this.isShow = false;
    },
  },
  computed:{
    selAll:{
      get(){
        let isAll = true;
        try {
          Object.keys(this.son).forEach(id=>{
            isAll = this.son[id].sel && isAll;
            if(!isAll){
              throw new Error('isFalse');
            }
          })
          return isAll;
        } catch (e) {
          if(e.message == 'isFalse'){
            return isAll;
          }
        }
      },
      set(v){
        Object.keys(this.son).forEach(id=>{
          this.son[id].sel = v;
        })
      }
    },
  },
  created(){
    this.reset();
  },
  mounted(){
    this.$nextTick(()=>{
      this.initStamp()
      hub.$on("updateSon", (pkgs)=>{
        this.updateSon(pkgs)
      })
    })
    
  }
}

window.hub = new Vue();

let app = document.createElement('div');
app.id = "app";
document.body.appendChild(app);
new Vue({
  el: '#app', 
  render: h=>h(appComp)
})

let multiInitButton = document.createElement('button');
multiInitButton.id = 'multiInitButton';
multiInitButton.textContent = '批量改价';
multiInitButton.setAttribute('class', 'btn btn-default');
let targetElementSelector = pageType()==='mother' ? "#batch-synchro" : '#setCost';
console.log(targetElementSelector);
document.querySelector(targetElementSelector).parentElement.appendChild(multiInitButton);
multiInitButton.addEventListener("click", ()=>{
  let packages = findAmuCheckPackages();
  hub.$emit('updateSon', packages);
});
